#! python3
#-*- coding:utf-8 -*-
# __author__ = 'GuanFengyu'


import os,re
import itertools
import tkinter.filedialog as fd
import tkinter.messagebox as mb
from tkinter import *

import xlrd
import xlwt

from myXlsStyles import *
from ToolDt2xls1 import DecisionTableToCase1


class DecisionTableToCase:
    def __init__(self):
        self.frame = Frame(width=550, height=350)
        self.text = "判定表生成测试案例"
        self.help = "Dt2xls工具使用说明"
        self.var_xls = StringVar()
        self.condition_num = StringVar()
        self.result_num = StringVar()
        self.set_frame()

        # self.var_xls.set('D:/WorkG/GenerateTestCasePy3/TestData/decision_table4.xls')
        # self.decision_table_to_case()
    
    # 选择xls文件
    def select_xls(self):
        path = fd.askopenfilename(initialdir = os.getcwd(),
                                  filetypes = [('xls files', '*.xls')])
        self.var_xls.set(path)
    
    # 判定表生成测试案例
    def decision_table_to_case(self):
        # 打开xls文件
        xlsFilename = self.var_xls.get()
        
        if xlsFilename == '':
            mb.showerror(title = "提示", message = "%s 文件路径不存在" % xlsFilename)
            return
        if not xlsFilename.endswith('.xls'):
            mb.showerror(title = '提示', message = '选择文件非xls结尾')
            return
        
        workbook = xlrd.open_workbook(xlsFilename,formatting_info=True)
        sheet_names = workbook.sheet_names()

        workbook_write = xlwt.Workbook(encoding='utf-8')

        for sheet_name in sheet_names:
            sheet = workbook.sheet_by_name(sheet_name)
            conditions, results = self.read_decision_sheet(sheet)
            self.write_case_sheet(workbook_write, sheet.name, conditions, results)

        try:
            wb_save_filename = self.var_xls.get()[:-4]+"_Case.xls"
            workbook_write.save(wb_save_filename)
            mb.showinfo(title = '提示',message = wb_save_filename + u'文件已保存到对应目录')
        except Exception:
            mb.showerror(title = '提示', message = u'没有选择保存文件名')
    
    def read_decision_sheet(self, sheet):
        condition_keywords = u'条件'
        condition_positive = [u'T', u'1', 1]
        condition_negtive  = [u'F', u'0', 0]
        step_text = u'步骤'
        
        nrows = sheet.nrows           #sheet行数
        # print("nrows:",nrows)         
        ncols = sheet.ncols           #sheet列数
        # print("ncols:",ncols)

        # 验证表格非空
        if nrows == 0 or ncols == 0:
            print('sheet maybe empty')
            return
        print('Sheet name:' + sheet.name)
        
        # 读取合并单元格，查找其中带关键字的
        condition_kw_rs, condition_kw_re, condition_kw_cs, condition_kw_ce = [-1, -1, -1, -1]    # [起始行，结束行，起始列，结束列]
        for crange in sheet.merged_cells:
            if sheet.cell_value(crange[0],crange[2]).find(condition_keywords) >= 0:
                condition_kw_rs, condition_kw_re, condition_kw_cs, condition_kw_ce = crange
                break
        if condition_kw_rs == -1:
            print('sheet format error')
            return
        
        # 获得条件名称
        condition_cnt = condition_kw_re - condition_kw_rs  # 条件个数
        condition_cols = condition_kw_ce   # 条件列
        #print("condition_cnt:",condition_cnt)
        #print("condition_cols:",condition_cols)
        
        conditions = []
        for condition_index in range(condition_kw_rs, condition_kw_re):#1-5
            conditions.append(sheet.cell_value(condition_index, condition_cols))
        
        # 获得结果
        results = []
        for result_index in range(condition_kw_re, nrows): #5-9
            res_str = sheet.cell_value(result_index,condition_cols)
            # print(res_str)
            if res_str:
                results.append(res_str)

        # 获得Case个数
        case_cols = condition_cols + 1
        case_cnt = ncols - case_cols
        print('Case number:' + str(case_cnt))
        # 按每个Case处理
        cases = []
        cases_result = []
        for case_index in range(case_cols, ncols):#2-16
            # 读取每个Case
            case = []
            step_index = 1
            for condition_index in range(condition_kw_rs, condition_kw_re):#1-5
                case_condition = step_text + str(step_index) + ':' + conditions[condition_index - condition_kw_rs]
                #print("case_condition",case_condition)
                case_value = sheet.cell_value(condition_index, case_index)
                # print("case_value",case_value)
                if case_value in condition_positive:
                    # print(case_value)
                    r = re.match(r"(步骤\d\:.*\:).*\(0\)\?(.*\(1\))",case_condition)
                    temp = r.group(1)+r.group(2)
                    case_condition =temp
                elif case_value in condition_negtive:
                    r = re.match(r"(步骤\d\:.*\:.*\(0\))\?.*\(1\)",case_condition)
                    temp = r.group(1)
                    case_condition =temp
                else:
                    continue
                step_index += 1
                case.append(case_condition)
                #print("case:",case)
            # 拼接
            case_str = u';\n'.join(case)
            cases.append(case_str)
            
            index = 0

            for i in range(condition_kw_re,nrows):#5-9
                
                case_result_value = sheet.cell_value(condition_kw_re+index, case_index)#5,2-15
                # print('case_result_value:'+str(case_result_value)+"test")
                if case_result_value:
                    # print("hehe:",case_result_value)
                    cases_result.append(results[index])
                index = index+1
                # print("cases_result:",cases_result)
        
        return cases, cases_result

    def write_case_sheet(self, wb, sheetname, conditions, results):
        if wb is None:
            return

        booksheet = wb.add_sheet(sheetname, cell_overwrite_ok=True)
        
        booksheet.write(0, 0, '案例名称', styleCommon)
        booksheet.write(0, 1, '步骤描述', styleCommon)
        booksheet.write(0, 2, '预期结果', styleCommon)
        booksheet.col(0).width = 256 * 40
        booksheet.col(1).width = 256 * 40


        for i in range(0, len(conditions)):
            booksheet.write(i + 1, 0, "案例"+str(i+1), styleCommon)
            booksheet.write(i + 1, 1, conditions[i], styleCommon)
        for i in range(0, len(results)):
            booksheet.write(i + 1, 0, "案例"+str(i+1), styleCommon)
            booksheet.write(i + 1, 2, results[i], styleCommon)        

    def generate_decision_table_template(self):
        condition_num = self.condition_num.get()
        result_num = self.result_num.get()
        if not condition_num.isdigit() or not result_num.isdigit():
            mb.showerror(title = "提示", message = "请输入整数")
            return
        condition_num = int(condition_num)
        result_num = int(result_num)
        if condition_num < 1 or condition_num > 10:
            mb.showerror(title = "提示", message = "条件个数超出范围(1,10)")
            return
        print("生成判定表条件个数:", condition_num)
        print("生成判定表结果个数:", result_num)
        conditions = []
        for i in range(condition_num):
            condition = u"条件" + str(i+1) + u":条件(0)?反条件(1)"
            conditions.append(condition)
        # print(conditions)
        results = []
        for i in range(result_num):
            result = u"结果" + str(i+1)
            results.append(result)
        cases_iter = itertools.product(range(2), repeat=condition_num)
        cases = [c for c in cases_iter]
        # cases.reverse()

        workbook_write = xlwt.Workbook(encoding='utf-8')
        booksheet = workbook_write.add_sheet("decision table template", cell_overwrite_ok=True)
        booksheet.write_merge(1, condition_num, 0, 0, u"条件桩", styleCenter)
        booksheet.write_merge(condition_num+1, condition_num+result_num, 0, 0, u"结果桩", styleCenter)
        booksheet.col(1).width = 256 * 40
        for i in range(condition_num):
            booksheet.write(i+1, 1, conditions[i])
        for i in range(result_num):
            booksheet.write(condition_num+i+1, 1, results[i])
        for i in range(len(cases)):
            booksheet.col(i+2).width = 256 * 4
            booksheet.write(0, i+2, i+1)
            for j in range(len(cases[i])):
                booksheet.write(j+1, i+2, cases[i][j])

        try:
            wb_save_filename = "./decision_table_template.xls"
            workbook_write.save(wb_save_filename)
            mb.showinfo(title = '提示',message = wb_save_filename + u'文件已保存到对应目录')
        except Exception:
            mb.showerror(title = '提示', message = u'保存失败，请检查文件是否被打开')

    def set_frame(self):
        # 标签
        Label(self.frame,text = '条件个数:').place(x=30, y=40)
        entry_xls = Entry(self.frame,textvariable=self.condition_num,width=15)
        entry_xls.place(x=120, y=40)
        Label(self.frame,text = '结果个数:').place(x=245, y=40)
        entry_xls = Entry(self.frame,textvariable=self.result_num,width=15)
        entry_xls.place(x=315, y=40)
        # 按钮
        Button(self.frame,text = '生成判定表',command = self.generate_decision_table_template, width=10, height = 1).place(x=450, y=35)

        # 标签
        Label(self.frame,text = 'excel文件:').place(x=30, y=120)
        entry_xls = Entry(self.frame,textvariable=self.var_xls,width=43)
        entry_xls.place(x=120, y=120)
        # 按钮
        Button(self.frame,text = '浏览',command = self.select_xls,height = 1, width=10).place(x=450, y=115)
        Button(self.frame, text='生成excel案例', command=self.decision_table_to_case).place(x=230, y=200)